/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */

package com.hbzhit.modules.act.service.impl;

import cn.hutool.core.util.StrUtil;
import com.hbzhit.common.exception.RRException;
import com.hbzhit.common.utils.ShiroUtils;
import com.hbzhit.modules.act.dao.TaskDao;
import com.hbzhit.modules.act.handle.WorkFlow;
import com.hbzhit.modules.act.handle.WorkFlowQuery;
import com.hbzhit.modules.act.handle.WorkFlowTask;
import com.hbzhit.modules.act.handle.WorkFlowTaskQuery;
import com.hbzhit.modules.act.service.TaskService;
import com.hbzhit.modules.sys.entity.SysDictValEntity;
import com.hbzhit.modules.sys.entity.SysUserEntity;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author lengleng
 * @date 2018/9/25
 */
@Slf4j
@Service("workFlowService")
@AllArgsConstructor
public class TaskServiceImpl implements TaskService {
    private final TaskDao taskDao;

    private final WorkFlow wfService;
    private final WorkFlowQuery wfQueryService;
    private final WorkFlowTask taskService;
    private final WorkFlowTaskQuery taskQueryService;
    private final RepositoryService repositoryService;
    private final ProcessEngineFactoryBean processEngine;

    /**
     * 追踪图片节点
     *
     * @param id 任务id
     */
    @Override
    public InputStream viewByTaskId(String id) {
        //使用当前任务ID，获取当前任务对象
        Task task = taskQueryService.createTaskQuery().taskId(id).singleResult();

        String processInstanceId = task.getProcessInstanceId();
        ProcessInstance processInstance = wfQueryService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        HistoricProcessInstance historicProcessInstance =
                wfQueryService.createHistoricProcessInstanceQuery()
                        .processInstanceId(processInstanceId).singleResult();
        String processDefinitionId = null;
        List<String> executedActivityIdList = new ArrayList<>();
        if (processInstance != null) {
            processDefinitionId = processInstance.getProcessDefinitionId();
            executedActivityIdList = wfQueryService.getActiveActivityIds(processInstance.getId());
        } else if (historicProcessInstance != null) {
            processDefinitionId = historicProcessInstance.getProcessDefinitionId();
            executedActivityIdList = wfQueryService.createHistoricActivityInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .orderByHistoricActivityInstanceId().asc().list()
                    .stream().map(HistoricActivityInstance::getActivityId)
                    .collect(Collectors.toList());
        }

        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        ProcessEngineConfigurationImpl processEngineConfiguration = processEngine.getProcessEngineConfiguration();
        Context.setProcessEngineConfiguration(processEngineConfiguration);
        ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();

        return diagramGenerator.generateDiagram(
                bpmnModel, "png",
                executedActivityIdList, Collections.emptyList(),
                processEngine.getProcessEngineConfiguration().getActivityFontName(),
                processEngine.getProcessEngineConfiguration().getLabelFontName(),
                "宋体",
                null, 1.0);

    }

    @Override
    public List<SysDictValEntity> countTypeTask(String tableName, String typeField, String typeCode) {
        SysUserEntity user = ShiroUtils.getUser();
        if (StrUtil.isBlank(tableName) || StrUtil.isBlank(typeField) || StrUtil.isBlank(typeCode)) {
            throw new RRException("参数不能为空");
        }
        return taskDao.countTypeTask(user.getId(), user.getOrgId(), tableName, typeField, typeCode);
    }

    @Override
    public Integer countTask(String tableName) {
        SysUserEntity user = ShiroUtils.getUser();
        if (StrUtil.isBlank(tableName)) {
            throw new RRException("参数不能为空");
        }
        return taskDao.countTask(user.getId(), user.getOrgId(), tableName);
    }

}
